package com.battle.service.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.battle.pojo.dto.authorization.GetAuthorizedByTargetIdDto;
import com.battle.pojo.dto.role.*;
import com.battle.pojo.entity.Role;
import com.battle.pojo.entity.User;
import com.battle.pojo.entity.UserRoleMp;
import com.battle.pojo.param.role.*;
import com.battle.pojo.vo.role.*;
import com.battle.service.repository.in.AuthorizationRepository;
import com.battle.service.repository.in.RoleRepository;
import com.battle.service.repository.in.UserRepository;
import com.battle.service.repository.in.UserRoleMpRepository;
import com.battle.service.service.in.RoleService;
import nirvana.core.domains.vo.PageResult;
import nirvana.core.exceptions.BizException;
import nirvana.core.utils.ids.IdGenerator;
import org.springframework.beans.BeanUtils;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 【描 述】：角色服务
 * 【环 境】：J2SE 17
 * 【详 细】：
 *
 */
@Service
public class RoleServiceImpl implements RoleService {

    private final RoleRepository roleRepository;
    private final ApplicationEventPublisher publisher;
    private final UserRepository userRepository;
    private final UserRoleMpRepository mpRepository;

    public RoleServiceImpl(RoleRepository roleRepository, ApplicationEventPublisher publisher, UserRepository userRepository, UserRoleMpRepository mpRepository) {
        this.roleRepository = roleRepository;
        this.publisher = publisher;
        this.userRepository = userRepository;
        this.mpRepository = mpRepository;
    }


    /**
     * 创建角色
     *
     * @param param
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createRole(CreateRoleParam param) {
        Role role = new Role();
        BeanUtils.copyProperties(param, role);
        Long id = IdGenerator.SNOW.generate();
        role.setId(id);
        role.setIsDisable(!param.getEnabled());

        if (CollectionUtil.isEmpty(param.getResourceCodeList())){
            throw new BizException("请配置权限");
        }
        role.setResourceCodeList(JSONUtil.toJsonStr(param.getResourceCodeList()));
        roleRepository.create(role);
    }

    /**
     * 修改角色
     *
     * @param param
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void editRole(EditRoleParam param) {
        Long id = param.getId();
        Role role = roleRepository.getByIdCheck(id);
        BeanUtils.copyProperties(param, role);
        role.setIsDisable(!param.getEnabled());


        if (CollectionUtil.isEmpty(param.getResourceCodeList())){
            throw new BizException("请配置权限");
        }
        role.setResourceCodeList(JSONUtil.toJsonStr(param.getResourceCodeList()));

        roleRepository.edit(role);
    }

    /**
     * 移除角色
     *
     * @param id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeRole(Long id) {
        Role role = roleRepository.getByIdCheck(id);
        if (role!=null && role.getIsSystem()!=null && role.getIsAdmin()!=null){
            if (role.getIsAdmin())throw new BizException("管理员角色不可删除");
            if (role.getIsSystem())throw new BizException("系统角色不可删除");
        }
        roleRepository.removeById(id);

        //删除角色和用户关联
        List<UserRoleMp> userRoleMpList = mpRepository.getBaseMapper().selectList(new LambdaQueryWrapper<UserRoleMp>()
                .eq(UserRoleMp::getRoleId, id)
                .eq(UserRoleMp::getIsDelete, Boolean.FALSE));
        if (CollectionUtil.isNotEmpty(userRoleMpList)){
            userRoleMpList.stream().map(UserRoleMp::getId).forEach(mpRepository::removeById);
        }
    }

    /**
     * 启动/禁用角色
     *
     * @param id
     */
    @Override
    public void enabledRole(Long id) {
        Role role = roleRepository.getByIdCheck(id);
        role.setIsDisable(!role.getIsDisable());
        roleRepository.edit(role);
    }

    /**
     * 获取角色详情
     *
     * @param id
     * @return
     */
    @Override
    public GetRoleVo getRole(Long id) {
        Role role = roleRepository.getByIdCheck(id);
        GetRoleVo vo = new GetRoleVo();
        BeanUtils.copyProperties(role, vo);
        vo.setEnabled(!role.getIsDisable());
        return vo;
    }

    /**
     * 获取角色 列表
     *
     * @param param
     * @return
     */
    @Override
    public PageResult<GetRoleListVo> getRoleList(GetRoleListParam param) {

        SelectRoleDto dto = new SelectRoleDto();
        BeanUtils.copyProperties(param, dto);
        Page<Role> page = roleRepository.selectRole(dto);

        List<Role> roleList = page.getRecords();
        List<GetRoleListVo> list = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(roleList)){

            //创建人
            List<Long> userIds = new ArrayList<>();
            roleList.forEach(v ->{
                userIds.add(v.getCreator());
            });

            Map<Long, User> userMap = userRepository.getMap(userIds);

            List<Long> roleIds = roleList.stream().map(Role::getId).toList();
            Map<Long, List<UserRoleDto>> listMap = roleRepository.getUserListByRoleIds(roleIds);

            for (Role role : roleList) {
                GetRoleListVo vo = new GetRoleListVo();
                BeanUtils.copyProperties(role, vo);
                vo.setEnabled(!role.getIsDisable());
                User create = userMap.get(role.getCreator());
                if (create != null) {
                    vo.setCreateName(create.getName());
                }
                List<UserRoleDto> roleDtoList = listMap.get(role.getId());
                if (roleDtoList != null) {
                    vo.setNumber(roleDtoList.size());
                }
                list.add(vo);
            }
        }
        return new PageResult<>(list, page);

    }

    /**
     * 获取角色下拉列表
     *
     * @param param
     * @return
     */
    @Override
    public List<GetRoleDownListVo> getRoleDownList(GetRoleDownListParam param) {
        Role po = new Role();
        if (param != null) {
            BeanUtils.copyProperties(param, po);
        }
        List<Role> roleList = roleRepository.getListByEntity(po);

        List<GetRoleDownListVo> list = new ArrayList<>();
        for (Role role : roleList) {
            GetRoleDownListVo vo = new GetRoleDownListVo();
            BeanUtils.copyProperties(role, vo);

            vo.setEnabled(!role.getIsDisable());
            list.add(vo);
        }
        return list;
    }

    /**
     * 创建管理员角色
     *
     * @param dto
     * @return
     */
    @Override
    public void createAdminRole(CreateAdminRoleDto dto) {
        Long roleId = dto.getRoleId();
        Role role = new Role();
        role.setId(roleId);
        role.setName("root");
        role.setIsSystem(Boolean.TRUE);
        roleRepository.create(role);
    }

    /**
     * 批量删除角色
     *
     * @param idList
     */
    @Override
    public void bathRemoveRole(List<Long> idList) {
        roleRepository.bathRemoveRole(idList);
    }

    /**
     * 根据部门id删除角色
     *
     * @param departmentIds
     */
    @Override
    public void removeRoleByDepartmentIds(List<Long> departmentIds) {
        roleRepository.removeRoleByDepartmentIds(departmentIds);
    }


}



